#pragma once

#include <gofcl_timer_smcfg.h>

typedef enum {
	TIMER_SMC_SLAVE_MODE_DISABLE = 0,
	TIMER_SMC_SLAVE_MODE_ENCODER_0 = 1,
	TIMER_SMC_SLAVE_MODE_ENCODER_1 = 2,
	TIMER_SMC_SLAVE_MODE_ENCODER_2 = 3,
	TIMER_SMC_SLAVE_MODE_RESTART = 4,
	TIMER_SMC_SLAVE_MODE_PAUSE = 5,
	TIMER_SMC_SLAVE_MODE_EVENT = 6,
	TIMER_SMC_SLAVE_MODE_EXTERNAL_CLOCK = 7,
} timer_smc_slave_mode_e;

typedef enum {
	TIMER_SMC_TRIGGER_SEL_ITI0 = 0,
	TIMER_SMC_TRIGGER_SEL_ITI1 = 1,
	TIMER_SMC_TRIGGER_SEL_ITI2 = 2,
	TIMER_SMC_TRIGGER_SEL_ITI3 = 3,
	TIMER_SMC_TRIGGER_SEL_CI0F_ED = 4,
	TIMER_SMC_TRIGGER_SEL_CI0FE0 = 5,
	TIMER_SMC_TRIGGER_SEL_CI1FE1 = 6,
	TIMER_SMC_TRIGGER_SEL_ETIFP = 6,
} timer_smc_trigger_sel_e;

typedef enum {
	TIMER_SMC_EXTERNAL_CLOCK_DIV_1_EVENT_DIV_1 = 0,
	TIMER_SMC_EXTERNAL_CLOCK_TIMER_CK_EVENT_DIV_2 = 1,
	TIMER_SMC_EXTERNAL_CLOCK_TIMER_CK_EVENT_DIV_4 = 2,
	TIMER_SMC_EXTERNAL_CLOCK_TIMER_CK_EVENT_DIV_8 = 3,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_2_EVENT_DIV_6 = 4,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_2_EVENT_DIV_8 = 5,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_4_EVENT_DIV_6 = 6,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_4_EVENT_DIV_8 = 7,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_8_EVENT_DIV_6 = 8,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_8_EVENT_DIV_8 = 9,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_16_EVENT_DIV_5 = 10,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_16_EVENT_DIV_6 = 11,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_16_EVENT_DIV_8 = 12,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_32_EVENT_DIV_5 = 13,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_32_EVENT_DIV_6 = 14,
	TIMER_SMC_EXTERNAL_CLOCK_DIV_32_EVENT_DIV_8 = 15,
} timer_smc_external_trigger_filter;

typedef enum {
	TIMER_SMC_EXTERNAL_POLARITY_HIGH_RISE = 0,
	TIMER_SMC_EXTERNAL_POLARITY_LOW_FALL = 1,
} timer_smc_external_trigger_polarity;

typedef struct {
	__attribute__((packed)) timer_smc_slave_mode_e slave_mode : 3;
	u16_s : 1;
	__attribute__((packed)) timer_smc_trigger_sel_e trigger_sel : 3;
	u16_s master_slave_mode_en : 1;
	__attribute__((packed))
	timer_smc_external_trigger_filter external_trigger_filter : 4;
	u16_s external_trigger_prescale_power_2 : 2;
	u16_s external_clock_mode_1_en : 1;
	__attribute__((packed))
	timer_smc_external_trigger_polarity external_trigger_polarity : 1;
} timer_smcfg_expl_s;

_Static_assert(sizeof(timer_smcfg_s) == 2,
	       "Struct timer_smcfg_s defined error!");

static inline void timer_setup_slave_mode(timer_qe timer_q,
					  timer_smcfg_expl_s smcfg) {
	union {
		timer_smcfg_expl_s e;
		timer_smcfg_s s;
	} es = {
		.e = smcfg,
	};
	timer_wreg_smcfg_s(timer_q, es.s);
}
